#ifndef __GRAPHIC_PARTICLE_EMITTER_POINT__
    #define __GRAPHIC_PARTICLE_EMITTER_POINT__

    // .. REFERENCES

    #include "object.h"
	#include "primitives.h"
    #include "graphic_particle_emitter.h"
    #include "math_curve_linear.h"
	#include "timer.h"
	#include "defs.h"

    // .. TYPES

    class GRAPHIC_PARTICLE_EMITTER_POINT :
        public GRAPHIC_PARTICLE_EMITTER
    {
        // -- PUBLIC

    public :

        // .. TYPES

        DECLARE_REF( GRAPHIC_PARTICLE_EMITTER_POINT );

        // .. CONSTRUCTORS

        GRAPHIC_PARTICLE_EMITTER_POINT();

        // .. ACCESSORS

        const REAL & GetDuration() const
        {
            return Duration;
        }

        // .. OPERATIONS

        virtual VOID Emit(
            GRAPHIC_PARTICLE_TABLE & particle_table,
            const TIMER & time_step
            );

        // ~~

        virtual VOID Reset();

        // ~~

        VOID AddPosition(
            const MATH_VECTOR_3 & position,
            const REAL & time = 0
            )
        {
            PositionCurve.AddPoint( time, position );
        }

        // ~~

        VOID AddPositionVariation(
            const MATH_VECTOR_3 & position,
            const REAL & time = 0
            )
        {
            PositionVariationCurve.AddPoint( time, position );
        }

        // ~~

        VOID AddDirection(
            const MATH_VECTOR_3 & direction,
            const REAL & time = 0
            )
        {            
            DirectionCurve.AddPoint( time, direction );
        }
 
        // ~~

        VOID AddDirectionAngleVariation(
            const REAL & angle,
            const REAL & time = 0
            )
        {            
            DirectionAngleVariationCurve.AddPoint( time, angle );
        }

        // ~~

        VOID AddAngle(
            const REAL & angle,
            const REAL & time = 0
            )
        {
            AngleCurve.AddPoint( time, angle );
        }

        // ~~

        VOID AddAngleVariation(
            const REAL & angle,
            const REAL & time = 0
            )
        {
            AngleVariationCurve.AddPoint( time, angle );
        }

        // ~~

        VOID AddSpin(
            const REAL & spin,
            const REAL & time = 0
            )
        {
            SpinCurve.AddPoint( time, spin );
        }

        // ~~

        VOID AddSpinVariation(
            const REAL & angle,
            const REAL & time = 0
            )
        {
            SpinVariationCurve.AddPoint( time, angle );
        }

        // ~~

        VOID AddEmitCount(
            const REAL count,
            const REAL & time = 0
            )
        {
            EmitCountCurve.AddPoint( time, count );
        }

        // ~~

        VOID AddVelocity(
            const REAL velocity,
            const REAL & time = 0
            )
        {
            VelocityCurve.AddPoint( time, velocity );
        }

        // ~~

        VOID AddVelocityVariation(
            const REAL velocity,
            const REAL & time = 0
            )
        {
            VelocityVariationCurve.AddPoint( time, velocity );
        }

        // ~~

        VOID AddLifeTime(
            const REAL life_time,
            const REAL & time = 0
            )
        {
            LifeTimeCurve.AddPoint( time, life_time );
        }

        // ~~

        VOID AddExtent(
            const MATH_VECTOR_2 & extent,
            const REAL & time = 0
            )
        {
            ExtentCurve.AddPoint( time, extent );
        }

        // ~~

        VOID AddExtentVariation(
            const MATH_VECTOR_2 & extent,
            const REAL & time = 0
            )
        {
            ExtentVariationCurve.AddPoint( time, extent );
        }

        // ~~

        VOID SetDuration(
            const REAL & duration
            )
        {
            Duration = duration;
            PositionCurve.SetDuration( duration );
            PositionVariationCurve.SetDuration( duration );
            DirectionCurve.SetDuration( duration );
            DirectionAngleVariationCurve.SetDuration( duration );
            AngleCurve.SetDuration( duration );
            AngleVariationCurve.SetDuration( duration );
            SpinCurve.SetDuration( duration );
            SpinVariationCurve.SetDuration( duration );
            EmitCountCurve.SetDuration( duration );
            VelocityCurve.SetDuration( duration );
            VelocityVariationCurve.SetDuration( duration );
            LifeTimeCurve.SetDuration( duration );
            ExtentCurve.SetDuration( duration );
            ExtentVariationCurve.SetDuration( duration );
        }

        // ~~

        VOID SetRate(
            const INT rate
            )
        {
            Rate = rate;
        }

        // -- PRIVATE

    private :

        // .. CONSTRUCTORS

        GRAPHIC_PARTICLE_EMITTER_POINT(
            const GRAPHIC_PARTICLE_EMITTER_POINT & other
            );

        // .. OPERATORS

        GRAPHIC_PARTICLE_EMITTER_POINT & operator=(
            const GRAPHIC_PARTICLE_EMITTER_POINT & other
            );

        // .. INQUIRIES

        const MATH_VECTOR_3 GenerateRandomDirection();

        // .. ATTRIBUTES

        MATH_CURVE_LINEAR< MATH_VECTOR_3 >
            PositionCurve,
            PositionVariationCurve,
            DirectionCurve;
        MATH_CURVE_LINEAR< REAL >
            DirectionAngleVariationCurve,
            AngleCurve,
            AngleVariationCurve,
            SpinCurve,
            SpinVariationCurve;
        MATH_CURVE_LINEAR< REAL >
            EmitCountCurve,
            VelocityCurve,
            VelocityVariationCurve,
            LifeTimeCurve;
        MATH_CURVE_LINEAR< MATH_VECTOR_2 >
            ExtentCurve,
            ExtentVariationCurve;
        MATH_VECTOR_3
            CurrentPosition,
            CurrentPositionVariation,
            CurrentDirection;
        REAL
            CurrentDirectionAngleVariation,
            CurrentAngle,
            CurrentAngleVariation,
            CurrentSpin,
            CurrentSpinVariation;
        REAL
            CurrentEmitCount,
            CurrentVelocity,
            CurrentVelocityVariation,
            CurrentLifeTime;
        MATH_VECTOR_2
            CurrentExtent,
            CurrentExtentVariation;
        REAL
            ParticleToEmitThreshold;
    };
#endif
